package mark.tom.sail;

import android.Manifest;
import android.content.Context;
import android.os.Environment;

import androidx.annotation.NonNull;
import androidx.core.content.PermissionChecker;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import static androidx.core.content.PermissionChecker.PERMISSION_GRANTED;
import static mark.tom.sail.C.UTF_8;
import static mark.tom.sail.Util.closeQuietly;
import static mark.tom.sail.Util.log_d;
import static mark.tom.sail.Util.log_e;

class DefaultFileStorage implements FileStorage {

    // 日志文件总文件夹名称
    private final static String CACHE_DIR = "sail";
    // 生命周期
    private final Context mContext;
    // 本地日志拦截器
    private final LogInterceptor logInterceptor;

    DefaultFileStorage(@NonNull Context mContext, @NonNull LogInterceptor logInterceptor) {
        this.mContext = mContext;
        this.logInterceptor = logInterceptor;
    }

    @Override
    public File getCacheDir() {
        String cachePath;
        if ((Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) || !Environment.isExternalStorageRemovable())
                && null != mContext.getExternalCacheDir()
                && PERMISSION_GRANTED == PermissionChecker.checkSelfPermission(mContext, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
            cachePath = mContext.getExternalCacheDir().getPath();
        } else {
            cachePath = mContext.getCacheDir().getPath();
        }
        File cacheDir = new File(cachePath + File.separator + CACHE_DIR);
        if (!cacheDir.exists()) {
            boolean mkResult = cacheDir.mkdirs();
            log_d(logInterceptor, "CacheDir Create " + mkResult);
        }
        return cacheDir;
    }

    @Override
    public List<String> getLogFileNamesInCacheDir() {
        File cacheDir = getCacheDir();
        if (cacheDir == null) {
            return null;
        }
        File[] childList = cacheDir.listFiles();
        if (null == childList || childList.length <= 0) {
            return null;
        }
        List<String> result = new ArrayList<>();
        for (File child : childList) {
            if (child != null && child.isFile()) {
                result.add(child.getName());
            }
        }
        return result.size() == 0 ? null : result;
    }

    @Override
    public boolean saveLogContent(@NonNull String fileName, @NonNull String data) {
        return saveLogContent(fileName, Collections.singletonList(data));
    }

    @Override
    public boolean saveLogContent(@NonNull String fileName, @NonNull List<String> data) {
        File cacheDir = getCacheDir();
        if (cacheDir == null) {
            return false;
        }

        File logFile = getLogFile(cacheDir, fileName);
        if (null == logFile) {
            return false;
        }
        boolean result = false;
        FileWriter writer = null;
        try {
            writer = new FileWriter(logFile, true);
            StringBuilder appendStr = new StringBuilder();
            for (int i = 0; i < data.size(); i++) {
                appendStr.append(data.get(i)).append("\r\n");
            }
            writer.write(appendStr.toString());
            result = true;
        } catch (IOException e) {
            log_e(logInterceptor, e.getMessage());
        } finally {
            closeQuietly(writer);
        }
        return result;
    }

    @Override
    public List<String> getLogContent(@NonNull String fileName) {
        File cacheDir = getCacheDir();
        if (cacheDir == null) {
            return null;
        }
        File logFile = getLogFile(cacheDir, fileName);
        if (logFile == null) {
            return null;
        }
        List<String> result = new ArrayList<>();
        BufferedReader reader = null;
        try {
            reader = new BufferedReader(new InputStreamReader(new FileInputStream(logFile), UTF_8));
            String tempString;
            while ((tempString = reader.readLine()) != null) {
                result.add(tempString);
            }
            reader.close();
        } catch (IOException e) {
            log_e(logInterceptor, e.getMessage());
        } finally {
            closeQuietly(reader);
        }
        return result.size() == 0 ? null : result;
    }

    @Override
    public boolean deleteLogFile(@NonNull String fileName) {
        File cacheDir = getCacheDir();
        if (cacheDir == null) {
            return true;
        }
        boolean result = false;
        File logFile = new File(cacheDir, fileName);
        if (logFile.exists() && logFile.isFile()) {
            try {
                result = logFile.delete();
            } catch (Exception ex) {
                log_e(logInterceptor, ex.getMessage());
            }
        }
        return result;
    }

    private File getLogFile(File cacheDir, String fileName) {
        File logFile = new File(cacheDir, fileName);
        boolean isFileRight = false;
        if (logFile.exists() && logFile.isFile()) {
            // 文件正常
            isFileRight = true;
        } else if (logFile.exists()) {
            // 删除该文件夹并重新创建该文件
            if (logFile.delete()) {
                // 创建该文件
                try {
                    isFileRight = logFile.createNewFile();
                } catch (Exception ex) {
                    log_e(logInterceptor, ex.getMessage());
                }
            }
        } else {
            // 创建该文件
            try {
                isFileRight = logFile.createNewFile();
            } catch (Exception ex) {
                log_e(logInterceptor, ex.getMessage());
            }
        }
        return isFileRight ? logFile : null;
    }
}
